﻿using System;
using System.Collections.Generic;
#if DEBUG
using System.Diagnostics;
#endif // #if DEBUG
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

using FRL.DebtChased.Repository;
using FRL.DebtChased.Repository.ViewModels;
using FRL.DebtChased.Website;
using FRL.DebtChased.WebServices;
using FRL.DebtChased.Types;

namespace WebApplication.Finance
{

	/// <summary>
	/// Declaration of AccountList
	/// </summary>
	public partial class AccountList : System.Web.UI.Page
	{

		/////////////////////////////////////////////////////////////
		// Constants and enumerations

		private const string ContextAccountIdTag = "ContactAccountId";
		private const string ContextTravelTypeTag = "TravelType";

		/////////////////////////////////////////////////////////////
		// Attributes

		private List<AccountTransport> m_accountTransportList = null;

		private int? ContextAccountId
		{
			get
			{
				return ViewState[ContextAccountIdTag] as int?;
			}
			set
			{
				ViewState[ContextAccountIdTag] = value;
			}
		}

		private CommOutTarget.eTravelType ContextTravelType
		{
			get
			{
				object ob = ViewState[ContextTravelTypeTag];
				if (ob == null)
					return CommOutTarget.eTravelType.NotSet;
				else
					return (CommOutTarget.eTravelType)ob;
			}
			set
			{
				ViewState[ContextTravelTypeTag] = value;
			}
		}

		private DebtChasedEntities m_ent = null;

		/////////////////////////////////////////////////////////////
		// Event handlers

		protected override void OnPreRender(EventArgs e)
		{

			// Call base-class function
			base.OnPreRender(e);

			// If there are some accounts to display...
			if (m_accountTransportList != null)
			{

				// Bind the grid
				gridAccounts.DataSource = m_accountTransportList;
				gridAccounts.DataBind();

			}
			else
			{

			}

			// Show/hide the account list panel
			pnlAccountList.Visible = (gridAccounts.Rows.Count > 0);

			// Show/hide the account details
			pnlAccountDetails.Visible = (ContextAccountId != null);

			// Show/hide the send-comm panel and controls
			CommOutTarget.eTravelType travelType = ContextTravelType;
			pnlSendComm.Visible = (travelType != CommOutTarget.eTravelType.NotSet);

			// Load the comm controls
			if (travelType != CommOutTarget.eTravelType.NotSet)
			{
#if DEBUG
				Debug.Assert(ContextAccountId != null);
#endif // #if DEBUG

				// Bodies
				Dictionary<int, string> bodyMap = null;
				switch (travelType)
				{
					case CommOutTarget.eTravelType.Email:
						bodyMap = CommBody.LoadDictionary(_safeGetEntities(), Definitions.eCommBodyType.Email);
						break;
					case CommOutTarget.eTravelType.Post:
						bodyMap = CommBody.LoadDictionary(_safeGetEntities(), Definitions.eCommBodyType.Letter);
						break;
					case CommOutTarget.eTravelType.Fax:
						bodyMap = CommBody.LoadDictionary(_safeGetEntities(), Definitions.eCommBodyType.Letter);
						break;
					case CommOutTarget.eTravelType.SMS:
						bodyMap = CommBody.LoadDictionary(_safeGetEntities(), Definitions.eCommBodyType.SMS);
						break;
				} // switch
				cboBody.BindToDictionary(bodyMap);
				if (cboBody.Items.Count > 0)
					cboBody.SelectedIndex = 0;

				// Get the target
				Definitions.eCommTargetType targetType = (Definitions.eCommTargetType) int.Parse(cboTarget.SelectedValue.ToString());

				// Get the contacts
				List<ContactTransport> contacts = Account.GetContacts(_safeGetEntities(), ContextAccountId.Value, targetType);

				// Build list of addresses and points
				List<string> strPoints = null;
				if (travelType == CommOutTarget.eTravelType.Post)
					strPoints = TransportSupportForWebsite.StripAllAddresses(contacts);
				else if (travelType == CommOutTarget.eTravelType.Email)
					strPoints = TransportSupportForWebsite.StripAllPoints(contacts,Definitions.eContactPointType.Email);
				else if (travelType == CommOutTarget.eTravelType.Fax)
					strPoints = TransportSupportForWebsite.StripAllPoints(contacts,Definitions.eContactPointType.Fax);

				// Bind to list
				chkTargetPoints.DataSource = strPoints;
				chkTargetPoints.DataBind();

				// Invoice checklist
				chkListInvoice.Items.Clear();
				for (int iRowIndex = 0; iRowIndex < gridInvoices.Rows.Count; iRowIndex++)
				{
					int iInvoiceId = int.Parse(gridInvoices.DataKeys[iRowIndex].Value.ToString());
					string strInvoiceNo = string.Format("{0}  {1}",
						gridInvoices.Rows[iRowIndex].Cells[1].Text,
						gridInvoices.Rows[iRowIndex].Cells[2].Text
					);
					chkListInvoice.Items.Add(new ListItem(strInvoiceNo, iInvoiceId.ToString()));
				}

			}

		}

		protected void Page_Load(object sender, EventArgs e)
		{

			// If this is a postback...
			if (this.IsPostBack)
			{

				//

			}
			else
			{

				// Set the search parameters
				DateTime dtNow = DateTime.Now;
				calSearchFrom.SelectedDate = dtNow.Date;
				calSearchTo.SelectedDate = dtNow.Date;

				// Color the panels
				MyApplication myApp = MyApplication.BindMyApplication();
				pnlSearch.BackColor = myApp.PrimaryWebColor;
				pnlAccountList.BackColor = myApp.PrimaryWebColor;
				pnlAccountDetails.BackColor = myApp.PrimaryWebColor;

				// Comm targets
				cboTarget.BindAndSelected(
					typeof(Definitions.eCommTargetType),
					(int)Definitions.eCommTargetType.Debtor,
					(int)Definitions.eCommTargetType.NotSet
				);

			}

		}

		protected void gridAccounts_RowDataBound(object sender, GridViewRowEventArgs e)
		{

			// If this is a data row...
			if (e.Row.RowType == DataControlRowType.DataRow)
			{

				// Get the account
				AccountTransport acc = e.Row.DataItem as AccountTransport;

				// Set rows
				e.Row.Cells[0].Text = acc.PrimaryClient.Name;

				e.Row.Cells[1].Text = acc.PrimaryClient.PrimaryContact.ComposeFullName();

				e.Row.Cells[2].Text = _getUserFullNameOrNone( acc.ManagerId );

				e.Row.Cells[3].Text = _getUserFullNameOrNone( acc.CollectorId );

				e.Row.Cells[4].Text = acc.AccountInvoices.Count.ToString();

				// Calculate total
				List<Money> moneyList = new List<Money>();
				foreach (AccountInvoiceTransport inv in acc.AccountInvoices)
					moneyList.Add(new Money(inv.Amount));
				e.Row.Cells[5].Text = Money.SuperSmartAddition(moneyList, true);

				if(acc.TradingStyle == 0)
					e.Row.Cells[8].Text = Definitions.None;
				else
					e.Row.Cells[8].Text = AccountTradingStyle.GetName(_safeGetEntities(), acc.TradingStyle);

			}

		}

		protected void butSearch_Click(object sender, EventArgs e)
		{

			// Validate contents
			this.Validate();
			if (!this.IsValid)
				return;

			// Clear the context
			ContextAccountId = null;

			// Get the search parameters
			DateTime dtFrom = DateTime.Now;
			DateTime dtTo = DateTime.Now;
			string strClient = null;

			// Load the list of models
			m_accountTransportList = Account.LoadAccountTransport(_safeGetEntities(), dtFrom, dtTo, strClient);

		}

		protected void gridAccounts_RowCommand(object sender, GridViewCommandEventArgs e)
		{

			// Compare command names
			if (e.CommandName == "Select")
			{

				// Get the row
				int iRowIndex = int.Parse(e.CommandArgument.ToString());
				ContextAccountId = int.Parse(gridAccounts.DataKeys[iRowIndex].Value.ToString());

				// Load the account transport
				AccountTransport account = Account.LoadAccountTransport(_safeGetEntities(), ContextAccountId.Value);
				if (account != null)
				{

					// Set the text
					ltFRLRef.Text = account.FRLReference;
					ltClientRef.Text = account.ClientReference;

					ltManager.Text = _getUserFullNameOrNone( account.ManagerId );
					ltCollector.Text = _getUserFullNameOrNone( account.CollectorId );

					ltDebtor.Text = account.DebtorName;

					ltTradingStyle.Text = _getTradingStyleNameOrNone( account.TradingStyle );

					if (account.ValidatedAt != null)
						ltValidated.Text = string.Format("{0:dd-MMM-yyyy} {1}",
							account.ValidatedAt,
							_getUserFullNameOrNone(account.ValidatedBy)
						);
					else
						ltValidated.Text = Definitions.NotValidated;

					// Set the invoices grid
					gridInvoices.DataSource = account.AccountInvoices;
					gridInvoices.DataBind();

					// Set the notes grid
					gridNotes.DataSource = account.Notes;
					gridNotes.DataBind();

				}

			}

		}

		protected void gridInvoices_RowDataBound(object sender, GridViewRowEventArgs e)
		{

			// If this is a data row...
			if (e.Row.RowType == DataControlRowType.DataRow)
			{

				// Get the account
				AccountInvoiceTransport inv = e.Row.DataItem as AccountInvoiceTransport;

				// Set rows
				e.Row.Cells[2].Text = new Money(inv.Amount).ToString();

				e.Row.Cells[3].Text = _getInvoiceStatusNameOrNone(inv.Status);

				if(inv.WorkflowId == 0)
					e.Row.Cells[4].Text = Definitions.NotAssigned;
				else
					e.Row.Cells[4].Text = Workflow.GetName(_safeGetEntities(),inv.WorkflowId);

			}

		}

		protected void gridNotes_RowDataBound(object sender, GridViewRowEventArgs e)
		{

			// If this is a data row...
			if (e.Row.RowType == DataControlRowType.DataRow)
			{

				// Get the note
				AccountNote note = e.Row.DataItem as AccountNote;

				// TODO 
				// Bind notes to grid

			}

		}

		private string _getUserFullNameOrNone(int iUserId)
		{

			// if user assigned...
			if (iUserId != 0)
				return FRL.DebtChased.Repository.User.GetFullName(_safeGetEntities(), iUserId);
			else
				return Definitions.None;

		}

		private string _getTradingStyleNameOrNone(int iTradingStyleId)
		{

			// If style assigned...
			if (iTradingStyleId != 0)
				return AccountTradingStyle.GetName(_safeGetEntities(), iTradingStyleId);
			else
				return Definitions.NotSet;

		}

		private string _getInvoiceStatusNameOrNone(int iAccountInvoiceStatusId)
		{

			// If status assigned...
			if (iAccountInvoiceStatusId != 0)
				return AccountInvoiceStatus.GetName(_safeGetEntities(), iAccountInvoiceStatusId);
			else
				return Definitions.None;

		}

		protected void butObliterate_Click(object sender, EventArgs e)
		{

			// Get the user id
			int iUserId = MySession.BindMySession().UserID;
#if DEBUG
			if(iUserId==0)
				iUserId = 1;
#endif // #if DEBUG

			// Delete this account
			string strError = Account.Obliterate(_safeGetEntities(), ContextAccountId.Value, iUserId);

			// Show error or reload
			if (strError != null)
				(Page.Master as FinanceMaster).ErrorMessage = strError;
			else
			{

				// Clear the context
				ContextAccountId = null;

				// Update the model
				butSearch_Click(null, null);
								
			}

		}

		protected void butSendLetter_Click(object sender, EventArgs e)
		{

			// Change mode
			ContextTravelType = CommOutTarget.eTravelType.Post;

		}

		protected void butSendSMS_Click(object sender, EventArgs e)
		{

			// Change mode
			ContextTravelType = CommOutTarget.eTravelType.SMS;

		}

		protected void butSendEmail_Click(object sender, EventArgs e)
		{

			// Change mode
			ContextTravelType = CommOutTarget.eTravelType.Email;

		}

		protected void butSendFax_Click(object sender, EventArgs e)
		{

			// Change mode
			ContextTravelType = CommOutTarget.eTravelType.Fax;

		}

		protected void butCancelComm_Click(object sender, EventArgs e)
		{

			// Change mode
			ContextTravelType = CommOutTarget.eTravelType.NotSet;

		}

		protected void butSendComm_Click(object sender, EventArgs e)
		{

			// Get the user id
			int iUserId = MySession.BindMySession().UserID;
#if DEBUG
			if (iUserId == 0)
				iUserId = 1;
#endif // #if DEBUG

			// 


			/*
			// Get the account, template and target
			int iAccountId = ContextAccountId.Value;
			int iTemplateId = int.Parse(cboTemplate.SelectedValue);
			Definitions.eCommTargetType Target = (Definitions.eCommTargetType) int.Parse(cboTarget.SelectedValue);

			// Get the selected invoice IDs
			List<int> iInvoiceIds = new List<int>();
			for (int iIndex = 0; iIndex < chkListInvoice.Items.Count; iIndex++)
			{
				ListItem li = chkListInvoice.Items[iIndex];
				if (li.Selected)
					iInvoiceIds.Add(int.Parse(li.Value));
			}

			// Get contact point or address id
			int iContactPointOrAddressId = 0;

			// Declare an entities object
			using (DebtChasedEntities ent = new DebtChasedEntities())
			{

				// Create a new comm-out
				CommOut.Queue(
					ent,
					iAccountId,
					iInvoiceIds,
					iTemplateId,
					Target,
					ContextTargetType,
					iContactPointOrAddressId,
					iUserId
				);

			}
			 */

			// Change mode
			ContextTravelType = CommOutTarget.eTravelType.NotSet;

			// Update error message
			(this.Master as FinanceMaster).ErrorMessage = "Please log on as SYSTEM_DEVELOPER to use this function.";

		}

		protected void cboTarget_SelectedIndexChanged(object sender, EventArgs e)
		{

			// Get the selected target

		}

		/////////////////////////////////////////////////////////////
		// Operations

		private DebtChasedEntities _safeGetEntities()
		{

			// If object needs declaring...
			if (m_ent == null)
				m_ent = new DebtChasedEntities();

			// Return reference
			return m_ent;

		}

	}

}